﻿using System;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;

using Castle.ActiveRecord;

using Light.Utility;
using Light.Framework.Contract;
using System.ComponentModel;

namespace Light.Framework.Model
{

    /// <summary>
    /// 实体基类
    /// </summary>
    [Serializable]
    public abstract class Entity : ActiveRecordBase, IEntity
    {
        internal protected readonly Hashtable table = new Hashtable();

        #region IEntity 成员

        /// <summary>
        /// 自增编号
        /// </summary>
        //[PrimaryKey(PrimaryKeyType.Identity)]
        [PrimaryKey(UnsavedValue = "-1")]
        [DisplayName("唯一标识")]
        public virtual Int32 ID { get; set; }

        /// <summary>
        /// 是否已删除
        /// </summary>
        [Property]
        [NonJsonSerialize]
        public virtual bool IsDeleted { get; set; }

        private DateTime timeCreated = DateTime.Now;
        /// <summary>
        /// 创建日期
        /// </summary>
        [Property]
        [ImportField("创建日期")]
        public virtual DateTime TimeCreated
        {
            get { return timeCreated; }
            set { timeCreated = value; }
        }

        private DateTime timeUpdated = DateTime.Now;
        /// <summary>
        /// 更新日期
        /// </summary>
        [Property]
        [DisplayName("更新日期")]
        [ImportField("更新日期")]
        public virtual DateTime TimeUpdated
        {
            get { return timeUpdated; }
            set { timeUpdated = value; }
        }

        /// <summary>
        /// 所属的组织机构
        /// </summary>
        [BelongsTo("Organization_ID")]
        public virtual Organization Organization { get; set; }

        /// <summary>
        /// 是否是新增项
        /// </summary>
        [NonJsonSerialize]
        public bool IsNew
        {
            get
            {
                return ID <= 0;
            }
        }

        /// <summary>
        /// 校验数据合法性
        /// </summary>
        /// <returns></returns>
        [NonJsonSerialize]
        public bool IsValidated
        {
            get
            {
                errorMessages.Clear();
                ValidateRules();
                return errorMessages.Count == 0;
            }
        }
        /// <summary>
        /// 获取错误消息
        /// </summary>
        /// <returns></returns>
        public string GetErrorMessage()
        {
            errorMessages.Clear();
            ValidateRules();
            return String.Join(" ", errorMessages.ToArray());
        }


        /// <summary>
        /// 添加数据检验规则
        /// </summary>
        protected virtual void ValidateRules()
        {

        }


        List<string> errorMessages = new List<string>();
        protected void AddValidateRules(bool validated, string message)
        {
            if (!validated)
            {
                errorMessages.Add(message + "；");
            }

        }


        #endregion


        /// <summary>
        /// 备用属性
        /// </summary>
        public string Tag { get; set; }

        /// <summary>
        /// yyyy-MM-dd格式化过的时间
        /// </summary>
        public virtual string TimeCreatedFormatted { get { return timeCreated.ToString("yyyy-MM-dd"); } }

        /// <summary>
        /// yyyy-MM-dd格式化过的时间
        /// </summary>
        public virtual string TimeUpdatedFormatted { get { return timeUpdated.ToString("yyyy-MM-dd"); } }


        /// <summary>
        /// 获取排序列信息列表
        /// </summary>
        /// <returns>返回Dictionary，Key:属性名; Value:显示名</returns>
        public Dictionary<string, string> GetOrderFields()
        {
            List<KeyValuePair<KeyValuePair<string, string>, int>> listSource = new List<KeyValuePair<KeyValuePair<string, string>, int>>();
            PropertyInfo[] properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            if ((properties != null) && (properties.Length > 0))
            {
                foreach (PropertyInfo info in properties) // ...
                {
                    SortableAttribute[] customAttributes = (SortableAttribute[])info.GetCustomAttributes(typeof(SortableAttribute), false);
                    if ((customAttributes != null) && (customAttributes.Length > 0))
                    {
                        foreach (SortableAttribute attribute in customAttributes) // ...
                        {
                            if ((attribute != null) && attribute.Sortable)
                            {
                                string columnName = info.Name;
                                string displayName = !string.IsNullOrEmpty(attribute.DisplayName) ? attribute.DisplayName : ReflectionHelper.GetDisplayName(info, string.Empty);
                                if (!listSource.Exists(delegate(KeyValuePair<KeyValuePair<string, string>, int> i) { return i.Key.Key == columnName; }))
                                {
                                    listSource.Add(new KeyValuePair<KeyValuePair<string, string>, int>(new KeyValuePair<string, string>(displayName, columnName), attribute.Index));
                                }
                            }
                        }
                    }
                }
            }

            listSource.Sort(delegate(KeyValuePair<KeyValuePair<string, string>, int> x, KeyValuePair<KeyValuePair<string, string>, int> y)
            {
                return x.Value.CompareTo(y.Value);
            });

            Dictionary<string, string> listData = new Dictionary<string, string>();
            int count = listSource.Count;
            for (int i = 0; i < count; i++) // ...
            {
                listData.Add(listSource[i].Key.Key, listSource[i].Key.Value);
            }
            return listData;
        }


        /// <summary>
        /// 获取搜索列信息列表
        /// </summary>
        /// <returns>返回Dictionary，Key:属性名; Value:显示名</returns>
        public Dictionary<string, string> GetSearchFields()
        {
            List<KeyValuePair<KeyValuePair<string, string>, int>> listSource = new List<KeyValuePair<KeyValuePair<string, string>, int>>();
            PropertyInfo[] properties = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
            if ((properties != null) && (properties.Length > 0))
            {
                foreach (PropertyInfo info in properties) // ...
                {
                    SearchableAttribute[] customAttributes = (SearchableAttribute[])info.GetCustomAttributes(typeof(SearchableAttribute), false);
                    if ((customAttributes != null) && (customAttributes.Length > 0))
                    {
                        foreach (SearchableAttribute attribute in customAttributes) // ...
                        {
                            if (attribute != null)
                            {
                                string columnName = !String.IsNullOrEmpty(attribute.PropertyName) ? attribute.PropertyName : info.Name;
                                string displayName = !string.IsNullOrEmpty(attribute.DisplayName) ? attribute.DisplayName : ReflectionHelper.GetDisplayName(info, string.Empty);

                                if (!listSource.Exists(delegate(KeyValuePair<KeyValuePair<string, string>, int> i) { return i.Key.Key == columnName; }))
                                {
                                    listSource.Add(new KeyValuePair<KeyValuePair<string, string>, int>(new KeyValuePair<string, string>(displayName, columnName), attribute.DisplayIndex));
                                }
                            }
                        }
                    }
                }
            }

            listSource.Sort(delegate(KeyValuePair<KeyValuePair<string, string>, int> x, KeyValuePair<KeyValuePair<string, string>, int> y)
            {
                return x.Value.CompareTo(y.Value);
            });

            Dictionary<string, string> listData = new Dictionary<string, string>();
            int count = listSource.Count;
            for (int i = 0; i < count; i++) // ...
            {
                listData.Add(listSource[i].Key.Key, listSource[i].Key.Value);
            }
            return listData;
        }


        public void SetValue(string key, object value)
        {
            if (!table.ContainsKey(key))
                table.Add(key, value);
            else
                table[key] = value;
        }

        public T GetValue<T>(string key)
        {
            T value = default(T);

            object obj = table[key];
            if (obj != null)
                value = (T)obj;

            return value;
        }

        public T GetValue<T>(string key, T defaultValue)
        {
            T value = defaultValue;

            object obj = table[key];
            if (obj != null && !String.IsNullOrEmpty(obj.ToString()))
                value = (T)obj;
            if (typeof(T) == typeof(DateTime) && ((DateTime)obj) == default(DateTime))
                value = defaultValue;

            return value;
        }
    }
}
